﻿using System;
using System.Threading;
using UnityEditor;
using UnityEngine;

public class ActionItemControl : TrackItemControl
{
    protected const float ITEM_RESIZE_HANDLE_SIZE = 5f;
    private static float mouseDownOffset = -1f;

    public event ActionItemEventHandler AlterAction;

    private bool doActionsConflict(float firetime, float endtime, float newFiretime, float newEndtime)
    {
        return (((newFiretime >= firetime) && (newFiretime <= endtime)) || ((firetime >= newFiretime) && (firetime <= newEndtime)));
    }

    public override void Draw(DirectorControlState state)
    {
        if (base.Wrapper.Behaviour != null)
        {
            GUIContent content = new GUIContent(base.Wrapper.Behaviour.name);
            if (Selection.activeGameObject == base.Wrapper.Behaviour.gameObject)
            {
                GUI.Box(base.controlPosition, content, TimelineTrackControl.styles.GlobalTrackItemSelectedStyle);
            }
            else
            {
                GUI.Box(base.controlPosition, content, TimelineTrackControl.styles.GlobalTrackItemStyle);
            }
        }
    }

    public override void HandleInput(DirectorControlState state, Rect trackPosition)
    {
        CinemaActionWrapper action = base.Wrapper as CinemaActionWrapper;
        if (action != null)
        {
            float left = (action.Firetime * state.Scale.x) + state.Translation.x;
            float num2 = ((action.Firetime + action.Duration) * state.Scale.x) + state.Translation.x;
            base.controlPosition = new Rect(left, 0f, num2 - left, trackPosition.height);
            Rect position = new Rect(left, 0f, 5f, this.controlPosition.height);
            Rect rect2 = new Rect(left + 5f, 0f, (num2 - left) - 10f, this.controlPosition.height);
            Rect rect3 = new Rect(num2 - 5f, 0f, 5f, this.controlPosition.height);
            EditorGUIUtility.AddCursorRect(position, MouseCursor.ResizeHorizontal);
            EditorGUIUtility.AddCursorRect(rect2, MouseCursor.SlideArrow);
            EditorGUIUtility.AddCursorRect(rect3, MouseCursor.ResizeHorizontal);
            base.controlID = GUIUtility.GetControlID(base.Wrapper.Behaviour.GetInstanceID(), FocusType.Passive, base.controlPosition);
            int controlID = GUIUtility.GetControlID(base.Wrapper.Behaviour.GetInstanceID(), FocusType.Passive, position);
            int num4 = GUIUtility.GetControlID(base.Wrapper.Behaviour.GetInstanceID(), FocusType.Passive, rect2);
            int num5 = GUIUtility.GetControlID(base.Wrapper.Behaviour.GetInstanceID(), FocusType.Passive, rect3);
            if (((Event.current.GetTypeForControl(base.controlID) == EventType.MouseDown) && rect2.Contains(Event.current.mousePosition)) && (Event.current.button == 1))
            {
                this.showContextMenu(base.Wrapper.Behaviour);
                Event.current.Use();
            }
            switch (Event.current.GetTypeForControl(num4))
            {
                case EventType.MouseDown:
                    if (rect2.Contains(Event.current.mousePosition) && (Event.current.button == 0))
                    {
                        GUIUtility.hotControl = num4;
                        Selection.activeInstanceID = base.Wrapper.Behaviour.GetInstanceID();
                        mouseDownOffset = ((Event.current.mousePosition.x - state.Translation.x) / state.Scale.x) - action.Firetime;
                        Event.current.Use();
                    }
                    break;

                case EventType.MouseUp:
                    if (GUIUtility.hotControl == num4)
                    {
                        mouseDownOffset = -1f;
                        GUIUtility.hotControl = 0;
                        if (this.AlterAction != null)
                        {
                            this.AlterAction(this, new ActionItemEventArgs(action.Behaviour, action.Firetime, action.Duration));
                        }
                    }
                    break;

                case EventType.MouseDrag:
                    if (GUIUtility.hotControl == num4)
                    {
                        float num6 = (Event.current.mousePosition.x - state.Translation.x) / state.Scale.x;
                        this.translateItem(base.Track, action, state, num6 - mouseDownOffset);
                    }
                    break;
            }
            switch (Event.current.GetTypeForControl(controlID))
            {
                case EventType.MouseDown:
                    if (position.Contains(Event.current.mousePosition))
                    {
                        GUIUtility.hotControl = controlID;
                        mouseDownOffset = ((Event.current.mousePosition.x - state.Translation.x) / state.Scale.x) - action.Firetime;
                        Event.current.Use();
                    }
                    break;

                case EventType.MouseUp:
                    if (GUIUtility.hotControl == controlID)
                    {
                        mouseDownOffset = -1f;
                        GUIUtility.hotControl = 0;
                        if (this.AlterAction != null)
                        {
                            this.AlterAction(this, new ActionItemEventArgs(action.Behaviour, action.Firetime, action.Duration));
                        }
                    }
                    break;

                case EventType.MouseDrag:
                    if (GUIUtility.hotControl == controlID)
                    {
                        float time = (Event.current.mousePosition.x - state.Translation.x) / state.Scale.x;
                        time = state.SnappedTime(time);
                        float a = 0f;
                        float num9 = action.Firetime + action.Duration;
                        foreach (TimelineItemWrapper wrapper2 in base.Track.Items)
                        {
                            CinemaActionWrapper wrapper3 = wrapper2 as CinemaActionWrapper;
                            if ((wrapper3 != null) && (wrapper3.Behaviour != base.Wrapper.Behaviour))
                            {
                                float b = wrapper3.Firetime + wrapper3.Duration;
                                if (b <= base.Wrapper.Firetime)
                                {
                                    a = Mathf.Max(a, b);
                                }
                            }
                        }
                        time = Mathf.Max(a, time);
                        time = Mathf.Min(num9, time);
                        action.Duration += base.Wrapper.Firetime - time;
                        action.Firetime = time;
                    }
                    break;
            }
            switch (Event.current.GetTypeForControl(num5))
            {
                case EventType.MouseDown:
                    if (rect3.Contains(Event.current.mousePosition))
                    {
                        GUIUtility.hotControl = num5;
                        mouseDownOffset = ((Event.current.mousePosition.x - state.Translation.x) / state.Scale.x) - base.Wrapper.Firetime;
                        Event.current.Use();
                    }
                    break;

                case EventType.MouseUp:
                    if (GUIUtility.hotControl == num5)
                    {
                        mouseDownOffset = -1f;
                        GUIUtility.hotControl = 0;
                        if (this.AlterAction != null)
                        {
                            this.AlterAction(this, new ActionItemEventArgs(action.Behaviour, action.Firetime, action.Duration));
                        }
                    }
                    break;

                case EventType.MouseDrag:
                    if (GUIUtility.hotControl == num5)
                    {
                        float num11 = (Event.current.mousePosition.x - state.Translation.x) / state.Scale.x;
                        num11 = state.SnappedTime(num11);
                        float positiveInfinity = float.PositiveInfinity;
                        foreach (TimelineItemWrapper wrapper4 in base.Track.Items)
                        {
                            CinemaActionWrapper wrapper5 = wrapper4 as CinemaActionWrapper;
                            if ((wrapper5 != null) && (wrapper5.Behaviour != base.Wrapper.Behaviour))
                            {
                                float num13 = action.Firetime + action.Duration;
                                if (wrapper5.Firetime >= num13)
                                {
                                    positiveInfinity = Mathf.Min(positiveInfinity, wrapper5.Firetime);
                                }
                            }
                        }
                        num11 = Mathf.Clamp(num11, base.Wrapper.Firetime, positiveInfinity);
                        action.Duration = num11 - base.Wrapper.Firetime;
                    }
                    break;
            }
            if (Selection.activeGameObject == base.Wrapper.Behaviour.gameObject)
            {
                if ((Event.current.type == EventType.ValidateCommand) && (Event.current.commandName == "Copy"))
                {
                    Event.current.Use();
                }
                if ((Event.current.type == EventType.ExecuteCommand) && (Event.current.commandName == "Copy"))
                {
                    DirectorCopyPaste.Copy(base.Wrapper.Behaviour);
                    Event.current.Use();
                }
            }
            if (((Event.current.type == EventType.KeyDown) && (Event.current.keyCode == KeyCode.Delete)) && (Selection.activeGameObject == base.Wrapper.Behaviour.gameObject))
            {
                base.deleteItem(base.Wrapper.Behaviour);
                Event.current.Use();
            }
        }
    }

    protected void translateItem(TimelineTrackWrapper track, CinemaActionWrapper action, DirectorControlState state, float newFireTime)
    {
        bool flag = true;
        float a = 0f;
        float positiveInfinity = float.PositiveInfinity;
        newFireTime = state.SnappedTime(newFireTime);
        float newEndtime = newFireTime + action.Duration;
        foreach (TimelineItemWrapper wrapper in track.Items)
        {
            CinemaActionWrapper wrapper2 = wrapper as CinemaActionWrapper;
            if ((wrapper2 != null) && (wrapper2.Behaviour != action.Behaviour))
            {
                float endtime = wrapper2.Firetime + wrapper2.Duration;
                float num5 = action.Firetime + action.Duration;
                if (this.doActionsConflict(wrapper2.Firetime, endtime, newFireTime, newEndtime))
                {
                    flag = false;
                }
                if (endtime <= action.Firetime)
                {
                    a = Mathf.Max(a, endtime);
                }
                if (wrapper2.Firetime >= num5)
                {
                    positiveInfinity = Mathf.Min(positiveInfinity, wrapper2.Firetime);
                }
            }
        }
        if (flag)
        {
            newFireTime = Mathf.Max(0f, newFireTime);
            action.Firetime = newFireTime;
        }
        else
        {
            newFireTime = Mathf.Max(a, newFireTime);
            newFireTime = Mathf.Min(positiveInfinity - action.Duration, newFireTime);
            action.Firetime = newFireTime;
        }
    }
}

